<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>手动实现一个eventEmitter</title>
  </head>
  <body>
    <script>
      class EventEmitter {
        constructor() {
          this._events = Object.create(null); // 定义事件的存储对象
          this._eventsCount = 0;
          this.app = "apple";
        }
        //添加事件监听
        on(eventName, fn, context, isOnce = false) {
          if (typeof fn !== "function") {
            throw new TypeError("The listener must be a function!");
          }
          if (!this._events[eventName]) {
            this._events[eventName] = [];
            this._events[eventName].push({ fn, context, isOnce });
          } else {
            this._events[eventName].push({ fn, context, isOnce }); // 存入监听的事件名和事件
          }
        }

        //一次性事件监听
        once(eventName, fn, context) {
          this.on(eventName, fn, context, true);
        }

        // 事件触发
        emit(eventName, ...args) {
          if (!this._events[eventName]) {
            return false;
          }
          const len = this._events[eventName].length;
          for (let i = 0; i < len; i++) {
            let event = this._events[eventName][i];
            event.fn.call(event.context, ...args);
            if (event.isOnce) {
              this.removeListener(eventName, event.fn);
              i--;
            }
          }
        }
        // 移除监听事件
        removeListener(eventName, fn) {
          if (!this._events[eventName]) return this;
          if (!fn) {
            delete this._events[eventName];
            return this;
          } else {
            this._events[eventName].forEach((item, index) => {
              if (item.fn === fn) {
                this._events[eventName].splice(index, 1);
              } else {
                return this;
              }
            });
          }
        }
        // off:removeListener 的别名
        off(eventName, fn) {
          this.removeListener(eventName, fn);
        }
        // 移除所有监听事件
        removeAllListener(eventName) {
          if (eventName) {
            if (this._events[eventName]) {
              this._events[eventName].length = 0;
            }
          } else {
            this._events = Object.create(null);
          }
        }
      }

      var app = "app";

      function add(...args) {
        let num = 0;
        for (let i = 0; i < args.length; i++) {
          num += args[i];
        }
        console.log(num);
        console.log(this.app);
        return num;
      }

      let event = new EventEmitter();
      event.on("adding", add,this);
      // event.emit("adding", 1, 2, 3, 4);
      // event.removeListener("adding", add);
      // event.emit("adding", 1, 2, 3, 4);
      // event.once("adding", add);
      event.emit("adding", 1, 2, 3, 4);
      event.emit("adding", 1, 2, 3, 4);
    </script>
  </body>
</html>
